// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//
#pragma once

#include <boost/random/uniform_int_distribution.hpp>
#include <pollux/plan/input_generator.h>
#include <pollux/testing/exec/result_verifier.h>

using namespace kumo::pollux::plan;

namespace kumo::pollux::exec::test {
    struct AggregationFuzzerOptions {
        /// Comma-separated list of functions to test. By default, all functions
        /// are tested.
        std::string onlyFunctions;

        /// Set of functions to not test.
        std::unordered_set<std::string> skipFunctions;

        /// Set of functions that should only be tested with sorted input.
        std::unordered_set<std::string> functionsRequireSortedInput;

        /// Set of functions whose results are non-deterministic. These can be
        /// order-dependent functions whose results depend on the order of input
        /// rows, or functions that return complex-typed results containing
        /// floating-point fields.
        ///
        /// For some functions, the result can be transformed to a deterministic
        /// value. If such transformation exists, it can be specified to be used for
        /// results verification. If no transformation is specified, results are not
        /// verified.
        ///
        /// Keys are function names. Values are optional transformations. "{}"
        /// should be used to indicate the original value, i.e. "f({})"
        /// transformation applies function 'f' to aggregation result.
        std::unordered_map<std::string, std::shared_ptr<ResultVerifier> >
        customVerificationFunctions;

        std::unordered_map<std::string, std::shared_ptr<InputGenerator> >
        customInputGenerators;

        std::unordered_set<std::string> orderDependentFunctions;

        /// Timestamp precision to use when generating inputs of type TIMESTAMP.
        VectorFuzzer::Options::TimestampPrecision timestampPrecision{
            VectorFuzzer::Options::TimestampPrecision::kMilliSeconds
        };

        /// A set of configuration properties to use when running query plans.
        /// Could be used to specify timezone or enable/disable settings that
        /// affect semantics of individual aggregate functions.
        std::unordered_map<std::string, std::string> queryConfigs;

        /// A set of hive configuration properties to use when running query plans.
        /// Could be used to specify different timestamp units for Presto and Spark
        /// fuzzer test.
        std::unordered_map<std::string, std::string> hiveConfigs;

        // Whether group keys must be orderable or be just comparable.
        bool orderableGroupKeys = false;
    };
} // namespace kumo::pollux::exec::test
